home *** CD-ROM | disk | FTP | other *** search
- (*===========================================================================*)
- (* Procedure to send/receive things to the tnc *)
- (* *)
- (* Copyright 1988, 1989, 1990, 1991 by H. Roy Engehausen. All rights *)
- (* reserved. *)
- (* *)
- (*===========================================================================*)
-
- {$DEFINE POINT_CHK}
- {$DEFINE FREE_CHK}
-
- {$UNDEF DEBUG_BLOCK}
- {$UNDEF DEBUG}
- {$DEFINE DEBUG_SRTQ} (* Turns trace on in SRTQ *)
-
- UNIT BBSRT;
-
- INTERFACE
-
- PROCEDURE send_recv_tnc(tnc_cmd_data : BYTE);
- FUNCTION garbage_collect_tnc : STRING;
- FUNCTION pending_chain(type_to_check : BYTE) : BYTE;
- PROCEDURE set_port_speed(speed : WORD);
- FUNCTION test_phone_connect : BOOLEAN;
-
- IMPLEMENTATION
-
- USES
- CRT,
- DOS,
- bbdummy,
- bbdump,
- bblstr,
- bbmisc3,
- bbsess,
- bbsema2,
- bbsrtbpq,
- bbstack,
- bbstr,
- bbtask,
- bbtime,
- bbtrace,
- bbwin;
-
- (*===========================================================================*)
- (* Get ASYNC Constants *)
- (*===========================================================================*)
-
- {$I 8250CON.PAS}
-
- (*===========================================================================*)
- (* Subroutines *)
- (*===========================================================================*)
-
- {$I BBSRTSEM.PAS} (* Semaphore *)
- {$I BBSRTGAR.PAS} (* Garbage collector *)
- {$I BBSRTPEN.PAS} (* Pending chain subroutines *)
- {$I BBSRTM.PAS} (* Miscellaneous *)
-
- (*===========================================================================*)
- (* Procedure to send/receive things to the tnc *)
- (* Parm = 0 -- Data *)
- (* 1 -- Command *)
- (* 2 -- General Poll *)
- (* 3 -- Data Poll *)
- (* 4 -- Link Status Poll *)
- (* 5 -- Issue JHOST1 *)
- (* 6 -- Force JHOST1 *)
- (*===========================================================================*)
-
- VAR
- master_thread : BOOLEAN;
- time_out_value : WORD;
-
- PROCEDURE send_recv_tnc(tnc_cmd_data : BYTE);
-
- (*-------------------------------------------------------------------------*)
- (* Local variables *)
- (*-------------------------------------------------------------------------*)
-
- VAR
- busy_char : ^CHAR;
- i : WORD;
- overlay_string : ^STRING;
- p_type : port_type_type;
- tnc_registers : REGISTERS;
-
- LABEL
- busy_loop;
-
- (*-------------------------------------------------------------------------*)
- (* Controls for the QRES handler. *)
- (*-------------------------------------------------------------------------*)
-
- VAR
- qres1_switch : BOOLEAN; (* First Pass for QRES *)
- qres2_switch : BOOLEAN; (* Second Pass for QRES *)
- qres_loop : BOOLEAN; (* Loop caused by QRES *)
- qres_resp : BOOLEAN; (* Response mode for QRES *)
-
- (*-------------------------------------------------------------------------*)
- (* Subroutines *)
- (*-------------------------------------------------------------------------*)
-
- {$I BBSRTQ.PAS} (* Queueing subroutines *)
- {XX BBSRTBYT.PAS} (* Byte mode I/O routines -- External TNC *)
- {$I BBSRTBLO.PAS} (* Block mode I/O routines - External TNC *)
- {$I BBSRTPCP.PAS} (* PC*PA I/O routines *)
- {$I BBSRT232.PAS} (* PK-232 I/O routines *)
- {$I BBSRTMOD.PAS} (* Telephone Modem *)
-
- BEGIN;
-
- (*-----------------------------------------------------------------------*)
- (* Show master thread *)
- (*-----------------------------------------------------------------------*)
-
- master_thread := active_tcb^.tcb_type = th_main;
-
- (*-----------------------------------------------------------------------*)
- (* Set timeout value *)
- (*-----------------------------------------------------------------------*)
-
- IF opt_block.opt_extend_timeout THEN
- time_out_value := 80 * up_ticks_per_sec
- ELSE
- time_out_value := 20 * up_ticks_per_sec;
-
- (*-----------------------------------------------------------------------*)
- (* Checkout *)
- (*-----------------------------------------------------------------------*)
-
- {$IFDEF POINT_CHK}
- test_pointer(active_tcb^.tnc_htt);
- test_pointer(active_tcb^.tnc_tth);
- {$ENDIF}
-
- (*-----------------------------------------------------------------------*)
- (* Go to other routines *)
- (*-----------------------------------------------------------------------*)
-
- p_type := active_port^.port_type;
-
- CASE p_type OF
-
- port_bpqhost:
- BEGIN;
- send_recv_tnc_BPQ(tnc_cmd_data);
- EXIT;
- END;
-
- port_g8bpq, port_aeapk232:
- BEGIN;
- send_recv_232(tnc_cmd_data);
- EXIT;
- END;
-
- port_modem:
- BEGIN;
- send_recv_modem(tnc_cmd_data);
- EXIT;
- END;
-
- ELSE;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Set the QRES switch as needed. QRES is a very special command to the *)
- (* TNC that tells it to do a restart. This will cause us to loose *)
- (* host mode so we must force it back into host mode. *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_tcb^.tnc_data DO
- IF (str_data = 'QRES') AND (tnc_cmd_data = info_cmd_cmd) THEN (* Transmission is command *)
- qres1_switch := TRUE
- ELSE
- qres1_switch := FALSE;
-
- qres2_switch := FALSE;
- qres_loop := FALSE;
- qres_resp := qres1_switch;
-
- (*-----------------------------------------------------------------------*)
- (* Initialize some variables *)
- (*-----------------------------------------------------------------------*)
-
- overlay_string := @active_tcb^.tnc_tth^.tnc_code;
-
- (*-----------------------------------------------------------------------*)
- (* This is where we loop to on a TNC busy *)
- (*-----------------------------------------------------------------------*)
-
- busy_loop:
-
- (*-----------------------------------------------------------------------*)
- (* Prevent execution if requested *)
- (*-----------------------------------------------------------------------*)
-
- WHILE active_tcb^.tcb_stop_tnc_io DO
- task_switch;
-
- (*-----------------------------------------------------------------------*)
- (* See if special poll code *)
- (*-----------------------------------------------------------------------*)
-
- IF tnc_cmd_data > 1 THEN
- WITH active_tcb^ DO
- BEGIN;
-
- CASE tnc_cmd_data OF
- 2: tnc_data.str_data := 'G';
- 3: tnc_data.str_data := 'G0';
- 4: tnc_data.str_data := 'G1';
- 5: tnc_data.str_data := 'JHOST1';
- 6: tnc_data.str_data := ^I^Q^X^['JHOST1'^M;
- END;
-
- tnc_cmd_data := info_cmd_cmd;
-
- tnc_data.long_length := LENGTH(tnc_data.str_data);
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Move the data to be sent into the TNC buffer *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_tcb^, active_tcb^.tnc_htt^ DO
- BEGIN;
-
- tnc_htt^.channel := active_tcb^.channel;
- info_cmd := tnc_cmd_data;
- i := tnc_data.long_length;
-
- IF (i = 0) OR (i > 256) THEN
- BEGIN;
- WRITELN(i ,' len rcvd', '-',
- LENGTH(tnc_data.str_data), '-', tnc_data.str_data);
- WRITELN(info_cmd);
- WRITELN('LL=', tnc_data.long_length,
- '-LD=', tnc_data.long_data[1]);
- END;
-
- data_count := i - 1;
- MOVE(tnc_data.long_data[1], data[1], i);
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Execute I/O in the correct manor *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_port^, active_tcb^ DO
- IF p_type = port_pc1xx THEN
- BEGIN;
-
- (*-----------------------------------------------------------------*)
- (* Handle the PC-1XX cards *)
- (*-----------------------------------------------------------------*)
-
- WITH tnc_registers DO
- BEGIN;
- AX := $0A00;
- DX := com_number - 1;
- DI := OFS(tnc_htt^);
- ES := SEG(tnc_htt^);
- END;
-
- INTR(tnc_interrupt, tnc_registers);
- END
- ELSE
- WITH active_port^ DO
- BEGIN;
-
- (*---------------------------------------------------------------*)
- (* Handle all other cards *)
- (*---------------------------------------------------------------*)
-
- (*---------------------------------------------------------------*)
- (* If we are not looping on a QRES then issue the locks *)
- (*---------------------------------------------------------------*)
-
- IF NOT qres_loop THEN
- BEGIN;
- get_port_semaphore;
- task_switch;
- END;
-
- (*---------------------------------------------------------------*)
- (* Send in BLOCK or PC*PA mode *)
- (*---------------------------------------------------------------*)
-
- CASE p_type OF
- port_pcpa : send_pcpa_mode;
- ELSE
- send_block_mode;
- END;
-
- (*---------------------------------------------------------------*)
- (* If we are in the QRES loop, need special garbage collect *)
- (*---------------------------------------------------------------*)
-
- IF qres_resp THEN
- BEGIN;
- IF qres1_switch THEN
- window_write('', 'QRES responses');
- i := 0;
- WHILE i < 800 DO
- BEGIN;
- INC(i);
- task_switch;
- overlay_string^ := garbage_collect_tnc;
- IF LENGTH(overlay_string^) <> 0 THEN
- BEGIN;
- window_write('', overlay_string^);
- i := 0;
- END;
- END;
- END;
-
- (*---------------------------------------------------------------*)
- (* If we just sent a QRES, set up for the JHOST1 *)
- (*---------------------------------------------------------------*)
-
- IF qres1_switch THEN
- BEGIN;
- qres1_switch := FALSE;
- qres2_switch := TRUE;
- qres_loop := TRUE;
- tnc_cmd_data := 6;
- GOTO busy_loop;
- END;
-
- (*---------------------------------------------------------------*)
- (* Second time thru for the QRES? If so we just did a JHOST1 *)
- (* so lets repeat it to confirm the mode *)
- (*---------------------------------------------------------------*)
-
- IF qres2_switch THEN
- BEGIN;
- qres2_switch := FALSE;
- qres_resp := FALSE;
- tnc_cmd_data := 5;
- GOTO busy_loop;
- END;
-
- (*---------------------------------------------------------------*)
- (* Free locks and let someone else run *)
- (*---------------------------------------------------------------*)
-
- free_port_semaphore;
-
- task_switch;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Special check for TNC busy *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_tcb^.tnc_tth^ DO
- IF tnc_code = t_to_h_badmsg THEN
- BEGIN;
- i := 1;
- WHILE (i < SIZEOF(t_to_h_busy)) AND (data15[i] = t_to_h_busy[i]) DO
- INC(i);
- IF i >= SIZEOF(t_to_h_busy) THEN
- BEGIN;
- window_write_critical('Busy TNC received -- ',
- active_port^.port_char);
- FOR i := 1 TO 50 DO
- task_switch;
- GOTO busy_loop;
- END;
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Move data from TNC buffer into data buffer *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_tcb^, active_tcb^.tnc_tth^ DO
- BEGIN;
-
- tnc_type := tnc_code;
- CASE tnc_type OF
- 0 : BEGIN;
- tnc_data.long_length := 0;
- tnc_data.str_data := '';
- END;
-
- 1..5: BEGIN;
- overlay_string^[0] := CHR(255);
- i := POS(CHR(0), overlay_string^);
- IF i = 0 THEN
- i := 255;
- overlay_string^[0] := CHR(i-1);
- l_move_str(@tnc_data, overlay_string^);
- END;
-
- 6..7: BEGIN;
- i := data67_count + 1;
- tnc_data.long_length := i;
- MOVE(data67, tnc_data.long_data, i);
- IF i > 255 THEN
- i := 255;
- tnc_data.str_data[0] := CHR(i);
- END;
- ELSE
- window_write_critical_i('Unknown response code from TNC -- '
- + active_port^.port_char
- + ' -- ',
- tnc_type);
- END;
-
- END;
-
- (*-----------------------------------------------------------------------*)
- (* Set null response if appropriate *)
- (*-----------------------------------------------------------------------*)
-
- WITH active_tcb^ DO
- tnc_null := tnc_data.long_length = 0;
-
- END; (*----- End main send/receive TNC ------------------------------------*)
-
- END.